package com.gitee.huanminabc.jcommon.container;

import java.util.*;

/**
 * 特性说明：
 * 去重：通过键保证唯一性，相同键的元素不会被重复添加。
 * 快速取值：使用 LinkedHashMap 实现 O (1) 时间复杂度的键查找。
 * 有序性：保持元素的插入顺序，poll() 操作始终返回最先插入的元素。
 * 队列操作：支持 add、poll、peek 等标准队列方法。
 * 使用场景：
 * 需要根据键快速访问元素的场景
 * 要求元素唯一且保持插入顺序的场景
 * 实现缓存、任务队列等功能
 * 注意事项：
 * 键（Key）不能为 null（LinkedHashMap 的限制）
 * 值（Value）可以为 null
 * 非线程安全，多线程环境下需外部同步或使用 Collections.synchronizedMap 包装
 * @param <K>
 * @param <V>
 */
public class OrderedKeyedUniqueQueue<K, V> {
    private final LinkedHashMap<K, V> map; // 维护插入顺序的 Map

    public OrderedKeyedUniqueQueue() {
        this.map = new LinkedHashMap<>();
    }

    /**
     * 添加元素到队列尾部（如果键不存在）
     * @param key 元素的键
     * @param value 元素的值
     * @return 如果键不存在且添加成功，返回 true；否则返回 false
     */
    public boolean add(K key, V value) {
        if (map.containsKey(key)) {
            return false; // 键已存在，不添加
        }
        map.put(key, value);
        return true;
    }

    /**
     * 通过键获取元素
     * @param key 元素的键
     * @return 元素的值，如果键不存在则返回 null
     */
    public V get(K key) {
        return map.get(key);
    }

    /**
     * 移除队列头部元素并返回
     * @return 队列头部元素的值，如果队列为空则返回 null
     */
    public V poll() {
        if (map.isEmpty()) {
            return null;
        }
        K firstKey = map.keySet().iterator().next();
        return map.remove(firstKey);
    }

    /**
     * 获取队列头部元素但不移除
     * @return 队列头部元素的值，如果队列为空则返回 null
     */
    public V peek() {
        if (map.isEmpty()) {
            return null;
        }
        K firstKey = map.keySet().iterator().next();
        return map.get(firstKey);
    }

    /**
     * 检查队列是否包含指定键
     * @param key 要检查的键
     * @return 如果包含返回 true，否则返回 false
     */
    public boolean containsKey(K key) {
        return map.containsKey(key);
    }

    /**
     * 获取队列大小
     * @return 队列中元素的数量
     */
    public int size() {
        return map.size();
    }

    /**
     * 检查队列是否为空
     * @return 如果为空返回 true，否则返回 false
     */
    public boolean isEmpty() {
        return map.isEmpty();
    }

    /**
     * 清空队列
     */
    public void clear() {
        map.clear();
    }

    /**
     * 获取队列中所有值的迭代器（按插入顺序）
     * @return 值的迭代器
     */
    public Iterator<V> iterator() {
        return map.values().iterator();
    }

    /**
     * 获取队列中所有键的集合（按插入顺序）
     * @return 键的集合
     */
    public Set<K> keySet() {
        return map.keySet();
    }

    /**
     * 获取队列中所有值的集合（按插入顺序）
     * @return 值的集合
     */
    public Collection<V> values() {
        return map.values();
    }

    @Override
    public String toString() {
        return map.toString();
    }

    // 示例使用
    public static void main(String[] args) {
        OrderedKeyedUniqueQueue<String, String> queue = new OrderedKeyedUniqueQueue<>();
        
        queue.add("k1", "value1");
        queue.add("k2", "value2");
        queue.add("k1", "value3"); // 重复键，添加失败
        
        System.out.println(queue); // 输出: {k1=value1, k2=value2}
        System.out.println(queue.get("k2")); // 输出: value2
        
        System.out.println(queue.poll()); // 输出: value1
        System.out.println(queue); // 输出: {k2=value2}
    }
}